﻿namespace EggOfPanKu.Library.Settings
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Configuration;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    using System.Text;

    /// <summary>
    /// An Application settings configuration section in the current application's settings.config file.
    /// </summary>
    public class AppSettings : CustomSettingsBase
    {
        #region Fields

        private const string _configFileName = "eopk.config";
        private const string _configSectionName = "EggAppSettings";

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="AppSettings"/> class.
        /// </summary>
        public AppSettings()
        {
        }

        #endregion Constructors

        #region Properties

        /// <summary>
        /// Gets or sets the name of the application.
        /// </summary>
        /// <value>The name of the application.</value>
        [ConfigurationProperty("ApplicationName")]
        public string ApplicationName
        {
            get
            {
                string retVal = this["ApplicationName"] as string;
                if (string.IsNullOrEmpty(retVal))
                {
                    retVal = "Egg of P'an Ku";
                    this["ApplicationName"] = retVal;
                    this.Save();
                }

                return retVal;
            }
            set
            {
                this["ApplicationName"] = value;
            }
        }

        /// <summary>
        /// Gets or sets the card image path.
        /// </summary>
        /// <value>The card image path.</value>
        [ConfigurationProperty("CardImagePath")]
        public string CardImagePath
        {
            get
            {
                string retVal = this["CardImagePath"] as string;
                if (string.IsNullOrEmpty(retVal))
                {
                    retVal = Path.Combine(ContentPath, "images\\cards");
                    if (!Directory.Exists(retVal))
                    {
                        retVal = string.Empty;
                    }
                    else
                    {
                        this["CardImagePath"] = retVal;
                        this.Save();
                    }
                }

                return retVal;
            }
            set
            {
                this["CardImagePath"] = value;
            }
        }

        /// <summary>
        /// Gets or sets the card XML path.
        /// </summary>
        /// <value>The card XML path.</value>
        [ConfigurationProperty("CardXmlPath")]
        public string CardXmlPath
        {
            get
            {
                string retVal = this["CardXmlPath"] as string;
                if (string.IsNullOrEmpty(retVal))
                {
                    retVal = Path.Combine(ContentPath, "cards.xml");
                    if (!File.Exists(retVal))
                    {
                        retVal = string.Empty;
                    }
                    else
                    {
                        this["CardXmlPath"] = retVal;
                        this.Save();
                    }
                }

                return retVal;
            }
            set
            {
                this["CardXmlPath"] = value;
            }
        }

        /// <summary>
        /// Gets or sets the cards can attach.
        /// </summary>
        /// <value>The cards can attach.</value>
        [ConfigurationProperty("CardsCanAttach")]
        public List<string> CardsCanAttach
        {
            get
            {
                string propVal = this["CardsCanAttach"] as string;
                List<string> retVal = new List<string>();
                if (string.IsNullOrEmpty(propVal))
                {
                    retVal.Add("Personality");
                    this["CardsCanAttach"] = string.Join(",", retVal.ToArray());
                    this.Save();
                }
                else
                {
                    retVal.AddRange(propVal.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries));
                }

                return retVal;
            }
            set
            {
                this["CardsCanAttach"] = value;
            }
        }

        /// <summary>
        /// Gets or sets the cards to draw.
        /// </summary>
        /// <value>The cards to draw.</value>
        [ConfigurationProperty("CardsToDraw")]
        public int CardsToDraw
        {
            get
            {
                string propVal = this["CardsToDraw"] as string;

                int retVal = 6; //defaults to 6 now

                if (string.IsNullOrEmpty(propVal))
                {
                    this["CardsToDraw"] = retVal;
                    this.Save();
                }
                else
                {
                    if (!int.TryParse(propVal, out retVal))
                    {
                        throw new ConfigurationErrorsException("The Application Setting \"CardsToDraw\" is not a proper number: " + propVal);
                    }
                }

                return retVal;
            }
            set
            {
                this["CardsToDraw"] = value;
            }
        }

        [ConfigurationProperty("ConnectionAddress")]
        public string ConnectionAddress
        {
            get
            {
                string retVal = this["ConnectionAddress"] as string;
                if (string.IsNullOrEmpty(retVal))
                {
                    retVal = "net.tcp://localhost:22222/chatservice";
                    this["ConnectionAddress"] = retVal;
                    this.Save();
                }

                return retVal;
            }
            set
            {
                this["ConnectionAddress"] = value;
            }
        }

        /// <summary>
        /// Gets or sets the name of the deck editor application.
        /// </summary>
        /// <value>The name of the deck editor application.</value>
        [ConfigurationProperty("DeckEditorApplicationName")]
        public string DeckEditorApplicationName
        {
            get
            {
                string retVal = this["DeckEditorApplicationName"] as string;
                if (string.IsNullOrEmpty(retVal))
                {
                    retVal = "DeckBuilder";
                    this["DeckEditorApplicationName"] = retVal;
                    this.Save();
                }

                return retVal;
            }
            set
            {
                this["DeckEditorApplicationName"] = value;
            }
        }

        /// <summary>
        /// Gets or sets the log level.
        /// </summary>
        /// <value>The log level.</value>
        [ConfigurationProperty("LogLevel")]
        public string LogLevel
        {
            get
            {
                string retVal = this["LogLevel"] as string;
                if (string.IsNullOrEmpty(retVal))
                {
                    retVal = "INFO";
                    this["LogLevel"] = retVal;
                    this.Save();
                }

                return retVal;
            }
            set
            {
                this["LogLevel"] = value;
            }
        }

        /// <summary>
        /// Gets or sets the log path.
        /// </summary>
        /// <value>The log path.</value>
        [ConfigurationProperty("LogPath")]
        public string LogPath
        {
            get
            {
                string retVal = this["LogPath"] as string;
                if (string.IsNullOrEmpty(retVal) || !Directory.Exists(retVal))
                {
                    retVal = Path.Combine(this.ContentPath, "logs");
                    if (!Directory.Exists(retVal))
                    {
                        Directory.CreateDirectory(retVal);
                    }
                    this["LogPath"] = retVal;
                    this.Save();
                }

                return retVal;
            }
            set
            {
                this["LogPath"] = value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether [log multiplayer games].
        /// </summary>
        /// <value>"true" if [log multiplayer games]; otherwise, "false".</value>
        [ConfigurationProperty("LogMultiplayerGames")]
        public bool LogMultiplayerGames
        {
            get
            {
                string propVal = this["LogMultiplayerGames"] as string;
                bool retVal = true;
                if (string.IsNullOrEmpty(propVal))
                {
                    this["LogMultiplayerGames"] = true;
                    this.Save();
                }
                else
                {
                    retVal = bool.Parse(propVal);
                }

                return retVal;
            }
            set
            {
                this["LogMultiplayerGames"] = value;
            }
        }

        /// <summary>
        /// Gets or sets the province spacing.
        /// </summary>
        /// <value>The province spacing.</value>
        [ConfigurationProperty("ProvinceSpacing")]
        public int ProvinceSpacing
        {
            get
            {
                string propVal = this["ProvinceSpacing"] as string;

                int retVal = 6; //defaults to 6 now

                if (string.IsNullOrEmpty(propVal))
                {
                    this["ProvinceSpacing"] = retVal;
                    this.Save();
                }
                else
                {
                    if (!int.TryParse(propVal, out retVal))
                    {
                        throw new ConfigurationErrorsException("The Application Setting \"ProvinceSpacing\" is not a proper number: " + propVal);
                    }
                }

                return retVal;
            }
            set
            {
                this["ProvinceSpacing"] = value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether [use CE holdings].
        /// </summary>
        /// <value>"true" if [use CE holdings]; otherwise, "false".</value>
        [ConfigurationProperty("UseCEHoldings")]
        public bool UseCEHoldings
        {
            get
            {
                string propVal = this["UseCEHoldings"] as string;
                bool retVal = true;
                if (string.IsNullOrEmpty(propVal))
                {
                    this["UseCEHoldings"] = true;
                    this.Save();
                }
                else
                {
                    retVal = bool.Parse(propVal);
                }

                return retVal;
            }
            set
            {
                this["UseCEHoldings"] = value;
            }
        }

        /// <summary>
        /// Gets the name of the configuration file.
        /// </summary>
        /// <value>The name of the configuration file.</value>
        protected override string ConfigurationFileName
        {
            get { return _configFileName; }
        }

        /// <summary>
        /// Gets the name of the configuration section.
        /// </summary>
        /// <value>The name of the configuration section.</value>
        protected override string ConfigurationSectionName
        {
            get { return _configSectionName; }
        }

        #endregion Properties
    }
}